<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>ServiceStack Examples :: Ajax Client</title>

    <link rel="stylesheet" type="text/css" href="default.css" />

    <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
    <script type="text/javascript" src="js/jquery-json.js"></script>
    <script type="text/javascript" src="js/JsonServiceClient.js"></script>

    <script type="text/javascript">
    <!--
        //Get the hostName of this page
        var url = location.href.substring(location.href.indexOf("://") + "://".length);
        var hostName = url.substring(0, url.indexOf('/'));

        //Create a JsonServiceClient passing in the baseUrl where your services are hosted.
        //Note: services not on the same domain require a crossdomain.xml policy
        var serviceClient = new JsonServiceClient("http://" + hostName + "/ServiceStack.Examples.Host.Web/");

        $(function()
        {

            $("#btnGetFactorial").click(function()
            {
                var request = { ForNumber: $("#txtGetFactorial").val() };

                serviceClient.getFromJsonService("GetFactorial", request, function(e)
                {
                    $("#serviceGetFactorial .result").html(e.result.Result);
                });
            });

            $("#btnGetFibonacciNumbers").click(function()
            {
                var request = { Skip: $("#txtGetFibonacciNumbersSkip").val(), Take: $("#txtGetFibonacciNumbersTake").val() };

                serviceClient.getFromJsonService("GetFibonacciNumbers", request, function(e)
                {
                    var resultHtml = "<ul>";
                    $(e.result.Results).each(function(i, fibNo)
                    {
                        resultHtml += "<li>" + fibNo + "</li>";
                    });
                    resultHtml += "</ul>";

                    $("#serviceGetFibonacciNumbers .result").html(resultHtml);
                });
            });

            $("#btnStoreNewUser").click(function()
            {
                var request = { UserName: $("#txtUserName").val(), Password: $("#txtUserName").val(), Email: $("#txtEmail").val() };

                serviceClient.postToJsonService("StoreNewUser", request, function(e)
                {
                    $("#serviceStoreNewUser .result").html(e.result.UserId);

                    var userIds = $("#txtUserIds").val();
                    if (userIds.length > 0) userIds += ",";
                    $("#txtUserIds").val(userIds + e.result.UserId);
                },
                function(ex)
                {
                    alert("Error creating new User: " + ex);
                });
            });

            $("#btnDeleteAllUsers").click(function()
            {
                serviceClient.postToJsonService("DeleteAllUsers", {},
                    function(e)
                    {
                        alert('All Users were deleted');
                        $("#txtUserIds").val("");
                    },
                    function(ex)
                    {
                        alert('Error deleting all users: ' + ex);
                    });
            });

            $("#btnGetUsers").click(function()
            {
                var request = { UserIds: $("#txtUserIds").val() };

                serviceClient.getFromJsonService("GetUsers", request, function(e)
                {
                    var resultHtml = "<div>";
                    $(e.result.Users).each(function(i, user)
                    {
                        resultHtml += '<div class="user">'
                            + user.UserName + "<br />"
                            + user.Email
                            + "</div>";
                    });
                    $("#serviceGetUsers .result").html(resultHtml);
                });
            });

            $(".code-link SPAN").click(function()
            {
                var link = $(this);
                var codePreview = link.next();
                if (codePreview.is(":visible"))
                {
                    codePreview.slideUp(function()
                    {
                        link.html("show");
                    });
                }
                else
                {
                    $(".code-preview").hide();
                    $(".code-link SPAN").html("show");
                    codePreview.fadeIn(function()
                    {
                        link.html("hide");
                    });
                }
            });

        });
    -->
    </script>

</head>
<body>

    <div id="header-links">
        <a href="Default.htm">Ajax Client Examples</a>
        <a href="Silverlight.htm">Silverlight Examples</a>
        <a href="../ServiceStack.Examples.Host.Web/AjaxClient/MovieRestTest.htm">REST examples</a>
    </div>

    <a href="http://www.servicestack.net"><img src="img/demo-logo-servicestack.png" alt="Service Stack Demo" /></a>

    <h1>Calling ServiceStack Web Services with Ajax</h1>

    <p>
        For performance reasons, the preferred to call ServiceStack services for Ajax clients
        is using JSON via the JSON endpoint at: <br />
        <em>~/Public/Json/SyncReply/{ServiceName}</em>
    </p>
    <p>
        As this endpoint is just a standard JSON service we can use any ajax client to call them with.
        In this example we're using a light-wrapper around jQuery's $.ajax client.
    </p>

    <h4>1. First step is to initialize the ServiceClient</h4>
    <code>
        //Create a JsonServiceClient passing in the baseUrl where your services are hosted.
        var serviceClient = new JsonServiceClient("http://" + hostName + "/ServiceStack.Examples.Host.Web/");
    </code>

    <h4>2. Ater that calling a service becomes as easy as:</h4>
    <code>
        var request = { ForNumber: $("#txtGetFactorial").val() };

        serviceClient.getFromJsonService("GetFactorial", request, function(e) {
            $("#serviceGetFactorial .result").html(e.result.Result);
        });
    </code>

    <h4>3. Try the live examples yourself:</h4>
    <div id="services">
        <div id="serviceGetFactorial" class="service">

                <div class="code-link">
                    <span>show</span>
                    <div class="code-preview">
                        <h5>Client code</h5>
                        <code class="client-code">
    var request = { ForNumber: $("#txtGetFactorial").val() };

    serviceClient.getFromJsonService("GetFactorial", request, function(e) {
        $("#serviceGetFactorial .result").html(e.result.Result);
    });
                        </code>
                        <div class="dtos">
                            <h5>Request and Response DataContracts (DTOs)</h5>
                            <code class="dto">
    [DataContract(Namespace = "http://schemas.sericestack.net/examples/types")]
    public class GetFactorial
    {
        [DataMember]
        public long ForNumber { get; set; }
    }

    [DataContract(Namespace = "http://schemas.sericestack.net/examples/types")]
    public class GetFactorialResponse
    {
        [DataMember]
        public long Result { get; set; }
    }
                            </code>
                        </div>
                        <h5>Server code</h5>
                        <code class="server-code">
	public class GetFactorialService : IService&lt;GetFactorial&gt;
	{
		public object Execute(GetFactorial request)
		{
			return new GetFactorialResponse { Result = GetFactorial(request.ForNumber) };
		}

		static long GetFactorial(long n)
		{
			return n &gt; 1 ? n * GetFactorial(n - 1) : 1;
		}
	}
                        </code>
                    </div>
                </div>

            <div class="input">
                <h3>Get Factorial Service</h3>
                <label>For Number:</label>
                <input class="int" type="text" id="txtGetFactorial" value="3" />
                <button id="btnGetFactorial">Go</button>
            </div>

            <h4>Result</h4>
            <div class="result"></div>
        </div>

        <div id="serviceGetFibonacciNumbers" class="service">

                <div class="code-link">
                    <span>show</span>
                    <div class="code-preview">
                        <h5>Client code</h5>
                        <code class="client-code">
    var request = {Skip: $("#txtGetFibonacciNumbersSkip").val(), Take:$("#txtGetFibonacciNumbersTake").val()};

    serviceClient.getFromJsonService("GetFibonacciNumbers", request, function(e)
    {
        var resultHtml = "&lt;ul&gt;";
        $(e.result.Results).each(function(i, fibNo)
        {
            resultHtml += "&lt;li&gt;" + fibNo + "&lt;/li&gt;";
        });
        resultHtml += "&lt;/ul&gt;";

        $("#serviceGetFibonacciNumbers .result").html(resultHtml);
    });
                        </code>
                        <div class="dtos">
                            <h5>Request and Response DataContracts (DTOs)</h5>
                            <code class="dto">
    [DataContract(Namespace = "http://schemas.sericestack.net/examples/types")]
    public class GetFibonacciNumbers
    {
        [DataMember]
        public long? Skip { get; set; }

        [DataMember]
        public long? Take { get; set; }
    }

    [DataContract(Namespace = "http://schemas.sericestack.net/examples/types")]
    public class GetFibonacciNumbersResponse
    {
        [DataMember]
        public ArrayOfLong Results { get; set; }
    }
                            </code>
                        </div>
                        <h5>Server code</h5>
                        <code class="server-code">
    public class GetFibonacciNumbersService 
	    : IService&lt;GetFibonacciNumbers&gt;
    {
	    private readonly ExampleConfig config;

	    //Example of ServiceStack's built-in Funq IOC constructor injection
	    public GetFibonacciNumbersService(ExampleConfig config)
	    {
		    this.config = config;
	    }

	    public object Execute(GetFibonacciNumbers request)
	    {
		    var skip = request.Skip.GetValueOrDefault(0);
		    var take = request.Take.GetValueOrDefault(config.DefaultFibonacciLimit);

		    var results = new List&lt;long&gt;();

		    var i = 0;
		    foreach (var fibonacciNumber in GetFibonacciNumbersNumbers())
		    {
			    if (i++ &lt; skip) continue;

			    results.Add(fibonacciNumber);

			    if (results.Count == take) break;
		    }

		    return new GetFibonacciNumbersResponse { Results = new ArrayOfLong(results) };
	    }

	    static IEnumerable&lt;long&gt; GetFibonacciNumbersNumbers()
	    {
		    long n1 = 0;
		    long n2 = 1;

		    while (true)
		    {
			    var n3 = n1 + n2;
			    yield return n3;
			    n1 = n2;
			    n2 = n3;
		    }
	    }
    }
                        </code>
                    </div>
                </div>

            <div class="input">

                <h3>Get Fibonacci Numbers Service</h3>

                <label>Skip:</label>
                <input class="int" type="text" id="txtGetFibonacciNumbersSkip" value="3" />

                <label>Take:</label>
                <input class="int" type="text" id="txtGetFibonacciNumbersTake" value="10" />

                <button id="btnGetFibonacciNumbers">Go</button>
            </div>

            <h4>Result</h4>
            <div class="result"></div>
        </div>

        <div id="serviceStoreNewUser" class="service">

                <div class="code-link">
                    <span>show</span>
                    <div class="code-preview">
                        <h5>Client code</h5>
                        <code class="client-code">
    var request = { UserName: $("#txtUserName").val(), Password: $("#txtUserName").val(),
                    Email: $("#txtEmail").val() };

    serviceClient.postToJsonService("StoreNewUser", request, function(e)
    {
        $("#serviceStoreNewUser .result").html(e.result.UserId);

        var userIds = $("#txtUserIds").val();
        if (userIds.length > 0) userIds += ",";
        $("#txtUserIds").val(userIds + e.result.UserId);
    },
    function(ex)
    {
        alert("Error creating new User: " + ex);
    });
                        </code>
                        <div class="dtos">
                            <h5>Request and Response DataContracts (DTOs)</h5>
                            <code class="dto">
    [DataContract(Namespace = "http://schemas.sericestack.net/examples/types")]
    public class StoreNewUser
    {
        [DataMember]
        public string UserName { get; set; }

        [DataMember]
        public string Email { get; set; }

        [DataMember]
        public string Password { get; set; }
    }

    [DataContract(Namespace = "http://schemas.sericestack.net/examples/types")]
    public class StoreNewUserResponse
    {
        public StoreNewUserResponse()
        {
            this.ResponseStatus = new ResponseStatus();
        }

        [DataMember]
        public long UserId { get; set; }

        [DataMember]
        public ResponseStatus ResponseStatus { get; set; }
    }
                            </code>
                        </div>
                        <h5>Server code</h5>
                        <code class="server-code">
    public class StoreNewUserService : IService&lt;StoreNewUser&gt;
    {
	    //Example of ServiceStack's built-in Funq IOC property injection
	    public IDbConnectionFactory ConnectionFactory { get; set; }

	    public object Execute(StoreNewUser request)
	    {
		    using (var dbConn = ConnectionFactory.OpenDbConnection())
		    using (var dbCmd = dbConn.CreateCommand())
		    {
			    var existingUsers = dbCmd.Select&lt;User&gt;("UserName = {0}", 
			      request.UserName).ToList();

			    if (existingUsers.Count &gt; 0)
			    {
				    return new StoreNewUserResponse {
					    ResponseStatus = new ResponseStatus { 
					      ErrorCode = "UserNameMustBeUnique" 
					    }
				    };
			    }

			    var newUser = new User { 
			        UserName = request.UserName, 
			        Email = request.Email, 
			        Password = request.Password 
			    };

			    dbCmd.Insert(newUser);

			    return new StoreNewUserResponse { UserId = dbCmd.GetLastInsertId() };
		    }
	    }
    }
                        </code>
                    </div>
                </div>

            <div class="input">
                <h3>Store New User Service</h3>

                <div class="form">
                    <label>User Name:</label>
                    <input type="text" id="txtUserName" value="User 1" />

                    <label>Password:</label>
                    <input type="text" id="txtPassword" value="password" />

                    <label>Email:</label>
                    <input type="text" id="txtEmail" value="as@if.com" />
                </div>

                <button id="btnStoreNewUser">Create New User</button>
            </div>

            <h4>Result</h4>
            <div class="result"></div>

            <button id="btnDeleteAllUsers">Delete All Users</button>
        </div>

        <div id="serviceGetUsers" class="service">

                <div class="code-link">
                    <span>show</span>
                    <div class="code-preview">
                        <h5>Client code</h5>
                        <code class="client-code">
    var request = { UserIds: $("#txtUserIds").val() };

    serviceClient.getFromJsonService("GetUsers", request, function(e)
    {
        var resultHtml = "&lt;div&gt;";
        $(e.result.Users).each(function(i, user)
        {
            resultHtml += '&lt;div class="user"&gt;'
            + user.UserName + "&lt;br /&gt;"
            + user.Email
            + "&lt;/div&gt;";
        });
        $("#serviceGetUsers .result").html(resultHtml);
    });
                        </code>
                        <div class="dtos">
                            <h5>Request and Response DataContracts (DTOs)</h5>
                            <code class="dto">
    [DataContract(Namespace = "http://schemas.sericestack.net/examples/types")]
    public class GetUsers
    {
        [DataMember]
        public ArrayOfLong UserIds { get; set; }

        [DataMember]
        public ArrayOfString UserNames { get; set; }
    }

    [DataContract(Namespace = "http://schemas.sericestack.net/examples/types")]
    public class GetUsersResponse
    {
        public GetUsersResponse()
        {
            this.ResponseStatus = new ResponseStatus();
        }

        [DataMember]
        public ArrayOfUser Users { get; set; }

        [DataMember]
        public ResponseStatus ResponseStatus { get; set; }
    }
                            </code>
                        </div>
                        <h5>Server code</h5>
                        <code class="server-code">
    public class GetUsersService : IService&lt;GetUsers&gt;
    {
	    //Example of ServiceStack's built-in Funq IOC property injection
	    public IDbConnectionFactory ConnectionFactory { get; set; }

	    public object Execute(GetUsers request)
	    {
		    using (var dbConn = ConnectionFactory.OpenDbConnection())
		    using (var dbCmd = dbConn.CreateCommand())
		    {
			    var users = new List&lt;User&gt;();

			    if (request.UserIds != null &amp;&amp; request.UserIds.Count &gt; 0)
			    {
				    users.AddRange(dbCmd.GetByIds&lt;User&gt;(request.UserIds));
			    }

			    if (request.UserNames != null &amp;&amp; request.UserNames.Count &gt; 0)
			    {
				    users.AddRange(dbCmd.Select&lt;User&gt;(
				        "UserName IN ({0})", request.UserNames.SqlInValues()));
			    }

			    return new GetUsersResponse { Users = new ArrayOfUser(users) };
		    }
	    }
    }
                        </code>
                    </div>
                </div>

            <div class="input">
                <h3>Get Users Service</h3>

                <div class="form">
                    <label>User Ids:</label>
                    <input type="text" id="txtUserIds" value="" />
                </div>

                <button id="btnGetUsers">Get Users</button>
            </div>

            <h4>Result</h4>
            <div class="result"></div>
        </div>

        <span class="r"></span>
    </div>

    <h4>4. Check out the other ways to call your services</h4>
    <p>
        One of the nice things about ServiceStack is that by using <acronym title="Plain Old CSharp Objects">POCO</acronym> classes to define your Service Interface
        we're able to seperate the 'message' (payload) from the communication 'channel' that delivers it.
    </p>
    <p>
        This means that calling your services using XML is as easy as sending your request to a different end point.
        So calling your service via XML is as easy as:
        <ol>
            <li><a href="/ServiceStack.Examples.Host.Web/Public/Xml/SyncReply/GetFactorial?ForNumber=3" target="_blank">
                Public/Xml/SyncReply/GetFactorial?ForNumber=3</a>
            </li>
            <li><a href="/ServiceStack.Examples.Host.Web/Public/Xml/SyncReply/GetFibonacciNumbers?Skip=3&Take=20" target="_blank">
                Public/Xml/SyncReply/GetFibonacciNumbers?Skip=3&Take=20</a>
            </li>
        </ol>
        <br />
        Out of the box ServiceStack provides REST+JSON, REST+XML and <acronym title="Plain Old XML">POX</acronym>, SOAP 1.1 and SOAP 1.2 end points.
    </p>
    <p>
        The dynamic <a href="/ServiceStack.Examples.Host.Web/Public/Metadata">metadata summary page</a>
        has a complete list of web services and end points that are available.<br />
    </p>

    <h4>5. Get the source code:</h4>
    <p>
        You can grab the source code for this example at
        <a href="http://code.google.com/p/servicestack/source/browse/#svn/trunk/ServiceStack.Examples/ServiceStack.Examples.Clients">
            http://code.google.com/p/servicestack/source/browse/#svn/trunk/ServiceStack.Examples/ServiceStack.Examples.Clients
        </a>
    </p>

    <div id="footer-links">
        <a href="http://mono-project.com/">
            <img src="img/Mono-powered-big.png" alt="powered by mono" />
        </a>

        <a href="http://www.ajaxstack.com">Ajax Stack</a> |
        <a href="http://www.servicestack.net">Service Stack</a>

    </div>

</body>
</html>
